﻿using DoNet.Core;
using DoNet.System.IRepositories;
using DoNet.System.Models;
using SqlSugar;
using System.Linq.Expressions;

namespace DoNet.System.Repositories
{
    public class OrganizeRepository : BaseRepository<Organize>, IOrganizeRepository
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        public OrganizeRepository(IServiceProvider serviceProvider) : base(serviceProvider)
        { }

        #region 同步方法

        #region 修改
        #region 数据有效性
        /// <summary>
        /// 同步根据主键Id设置数据有效性
        /// </summary>
        /// <param name="enabledMark">有效性标识 DeleteMark设置为true有效 false无效</param>
        /// <param name="lastModifyUserId">最后操作人Id</param>
        /// <param name="lastModifyTime">最后操作时间</param>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public virtual bool SetEnabledMark(bool enabledMark, long lastModifyUserId, DateTime lastModifyTime, long id)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { EnabledMark = enabledMark, LastModifyUserId = lastModifyUserId, LastModifyTime = lastModifyTime };
            return Update(columns, id);
        }
        /// <summary>
        /// 同步根据主键Id列表设置数据有效性
        /// </summary>
        /// <param name="enabledMark">有效性标识 DeleteMark设置为true有效 false无效</param>
        /// <param name="lastModifyUserId">最后操作人Id</param>
        /// <param name="lastModifyTime">最后操作时间</param>
        /// <param name="ids">主键Id列表</param>
        /// <returns></returns>
        public virtual bool SetEnabledMark(bool enabledMark, long lastModifyUserId, DateTime lastModifyTime, IEnumerable<long> ids)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { EnabledMark = enabledMark, LastModifyUserId = lastModifyUserId, LastModifyTime = lastModifyTime };
            Expression<Func<Organize, bool>> where = x => ids.Contains(x.Id);
            return Update(columns, where);
        }
        /// <summary>
        /// 同步根据条件设置数据有效性
        /// </summary>
        /// <param name="enabledMark">有效性标识 DeleteMark设置为true有效 false无效</param>
        /// <param name="lastModifyUserId">最后操作人Id</param>
        /// <param name="lastModifyTime">最后操作时间</param>
        /// <param name="whereSql">条件语句 如："Age > @Age"</param>
        /// <param name="parameters">条件参数 如：new { Age = 30 }</param>
        /// <returns>返回影响的行数</returns>
        public virtual bool SetEnabledMark(bool enabledMark, long lastModifyUserId, DateTime lastModifyTime, string whereSql = "", object? parameters = null)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { EnabledMark = enabledMark, LastModifyUserId = lastModifyUserId, LastModifyTime = lastModifyTime };
            return Update(columns, whereSql, parameters);
        }
        #endregion 数据有效性
        #region 逻辑删除
        /// <summary>
        /// 同步根据主键Id逻辑删除信息
        /// </summary>
        /// <param name="deleteMark">软删除标识 deleteMark设置为true删除 false未删除</param>
        /// <param name="deleteUserId">删除人Id</param>
        /// <param name="deleteTime">删除时间</param>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public virtual bool SetDeleteMark(bool deleteMark, long deleteUserId, DateTime deleteTime, long id)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { LastModifyUserId = deleteUserId, LastModifyTime = deleteTime, DeleteMark = deleteMark, DeleteTime = deleteTime, DeleteUserId = deleteUserId };
            return Update(columns, id);
        }
        /// <summary>
        /// 同步根据主键Id列表逻辑删除信息
        /// </summary>
        /// <param name="deleteMark">软删除标识 deleteMark设置为true删除 false未删除</param>
        /// <param name="deleteUserId">删除人Id</param>
        /// <param name="deleteTime">删除时间</param>
        /// <param name="ids">主键Id列表</param>
        /// <returns></returns>
        public virtual bool SetDeleteMark(bool deleteMark, long deleteUserId, DateTime deleteTime, IEnumerable<long> ids)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { LastModifyUserId = deleteUserId, LastModifyTime = deleteTime, DeleteMark = deleteMark, DeleteTime = deleteTime, DeleteUserId = deleteUserId };
            Expression<Func<Organize, bool>> where = x => ids.Contains(x.Id);
            return Update(columns, where);
        }
        /// <summary>
        /// 同步根据条件逻辑删除信息
        /// </summary>
        /// <param name="deleteMark">软删除标识 deleteMark设置为true删除 false未删除</param>
        /// <param name="deleteUserId">删除人Id</param>
        /// <param name="deleteTime">删除时间</param>
        /// <param name="whereSql">条件语句 如："Age > @Age"</param>
        /// <param name="parameters">条件参数 如：new { Age = 30 }</param>
        /// <returns>返回影响的行数</returns>
        public virtual bool SetDeleteMark(bool deleteMark, long deleteUserId, DateTime deleteTime, string whereSql = "", object? parameters = null)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { LastModifyUserId = deleteUserId, LastModifyTime = deleteTime, DeleteMark = deleteMark, DeleteTime = deleteTime, DeleteUserId = deleteUserId };
            return Update(columns, whereSql, parameters);
        }
        #endregion 逻辑删除
        #endregion 修改

        #region 查询
        /// <summary>
        /// 同步根据主键Id列表获取集合数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public IEnumerable<Organize> GetListByIds(IEnumerable<long> ids)
        {
            return GetListByWhere(x => ids.Contains(x.Id));
        }
        /// <summary>
        /// 同步根据节点Id获取子节点集合
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public IEnumerable<Organize> GetChildListById(long id)
        {
            return Db.Queryable<Organize>().ToChildList(x => x.ParentId, id);
        }
        /// <summary>
        /// 同步根据节点Id获取父节点集合
        /// </summary>
        /// <param name="pid"></param>
        /// <returns></returns>
        public IEnumerable<Organize> GetParentListById(long id)
        {
            return Db.Queryable<Organize>().ToParentList(x => x.ParentId, id);
        }
        /// <summary>
        /// 同步获取父集，递归调用
        /// </summary>
        /// <param name="data"></param>
        /// <param name="id">Id</param>
        /// <returns></returns>
        public IEnumerable<Organize> GetParentOrganizes(IEnumerable<Organize> data, long id)
        {
            List<Organize> list = new List<Organize>();
            var organize = data.ToList().FindAll(x => x.Id == id).FirstOrDefault();
            if (organize != null)
            {
                if (organize.ParentId > 0)
                {
                    var ChilList = data.ToList().FindAll(x => x.ParentId == organize.ParentId);
                    foreach (Organize entity in ChilList)
                    {
                        organize.Child = GetParentOrganizes(data, entity.Id).OrderBy(x => x.SortCode).ToList();
                        list.Add(organize);
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 同步获取子集，递归调用
        /// </summary>
        /// <param name="data"></param>
        /// <param name="parentId">父级Id</param>
        /// <returns></returns>
        public IEnumerable<Organize> GetChiltOrganizes(IEnumerable<Organize> data, long parentId)
        {
            List<Organize> list = new List<Organize>();
            var ChilList = data.ToList().FindAll(x => x.ParentId == parentId);
            foreach (Organize entity in ChilList)
            {
                entity.Child = GetChiltOrganizes(data, entity.Id).OrderBy(x => x.SortCode).ToList();
                list.Add(entity);
            }
            return list;
        }
        #endregion 查询

        #endregion 同步方法

        #region 异步方法

        #region 修改
        #region 数据有效性
        /// <summary>
        /// 异步根据主键Id设置数据有效性
        /// </summary>
        /// <param name="enabledMark">有效性标识 DeleteMark设置为true有效 false无效</param>
        /// <param name="lastModifyUserId">最后操作人Id</param>
        /// <param name="lastModifyTime">最后操作时间</param>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public virtual async Task<bool> SetEnabledMarkAsync(bool enabledMark, long lastModifyUserId, DateTime lastModifyTime, long id)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { EnabledMark = enabledMark, LastModifyUserId = lastModifyUserId, LastModifyTime = lastModifyTime };
            return await UpdateAsync(columns, id);
        }
        /// <summary>
        /// 异步根据主键Id列表设置数据有效性
        /// </summary>
        /// <param name="enabledMark">有效性标识 DeleteMark设置为true有效 false无效</param>
        /// <param name="lastModifyUserId">最后操作人Id</param>
        /// <param name="lastModifyTime">最后操作时间</param>
        /// <param name="ids">主键Id列表</param>
        /// <returns></returns>
        public virtual async Task<bool> SetEnabledMarkAsync(bool enabledMark, long lastModifyUserId, DateTime lastModifyTime, IEnumerable<long> ids)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { EnabledMark = enabledMark, LastModifyUserId = lastModifyUserId, LastModifyTime = lastModifyTime };
            Expression<Func<Organize, bool>> where = x => ids.Contains(x.Id);
            return await UpdateAsync(columns, where);
        }
        /// <summary>
        /// 异步根据条件设置数据有效性
        /// </summary>
        /// <param name="enabledMark">有效性标识 DeleteMark设置为true有效 false无效</param>
        /// <param name="lastModifyUserId">最后操作人Id</param>
        /// <param name="lastModifyTime">最后操作时间</param>
        /// <param name="whereSql">条件语句 如："Age > @Age"</param>
        /// <param name="parameters">条件参数 如：new { Age = 30 }</param>
        /// <returns>返回影响的行数</returns>
        public virtual async Task<bool> SetEnabledMarkAsync(bool enabledMark, long lastModifyUserId, DateTime lastModifyTime, string whereSql = "", object? parameters = null)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { EnabledMark = enabledMark, LastModifyUserId = lastModifyUserId, LastModifyTime = lastModifyTime };
            return await UpdateAsync(columns, whereSql, parameters);
        }
        #endregion 数据有效性
        #region 逻辑删除
        /// <summary>
        /// 异步根据主键Id逻辑删除信息
        /// </summary>
        /// <param name="deleteMark">软删除标识 deleteMark设置为true删除 false未删除</param>
        /// <param name="deleteUserId">删除人Id</param>
        /// <param name="deleteTime">删除时间</param>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public virtual async Task<bool> SetDeleteMarkAsync(bool deleteMark, long deleteUserId, DateTime deleteTime, long id)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { LastModifyUserId = deleteUserId, LastModifyTime = deleteTime, DeleteMark = deleteMark, DeleteTime = deleteTime, DeleteUserId = deleteUserId };
            return await UpdateAsync(columns, id);
        }
        /// <summary>
        /// 异步根据主键Id列表逻辑删除信息
        /// </summary>
        /// <param name="deleteMark">软删除标识 deleteMark设置为true删除 false未删除</param>
        /// <param name="deleteUserId">删除人Id</param>
        /// <param name="deleteTime">删除时间</param>
        /// <param name="ids">主键Id列表</param>
        /// <returns></returns>
        public virtual async Task<bool> SetDeleteMarkAsync(bool deleteMark, long deleteUserId, DateTime deleteTime, IEnumerable<long> ids)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { LastModifyUserId = deleteUserId, LastModifyTime = deleteTime, DeleteMark = deleteMark, DeleteTime = deleteTime, DeleteUserId = deleteUserId };
            Expression<Func<Organize, bool>> where = x => ids.Contains(x.Id);
            return await UpdateAsync(columns, where);
        }
        /// <summary>
        /// 异步根据条件逻辑删除信息
        /// </summary>
        /// <param name="deleteMark">软删除标识 deleteMark设置为true删除 false未删除</param>
        /// <param name="deleteUserId">删除人Id</param>
        /// <param name="deleteTime">删除时间</param>
        /// <param name="whereSql">条件语句 如："Age > @Age"</param>
        /// <param name="parameters">条件参数 如：new { Age = 30 }</param>
        /// <returns>返回影响的行数</returns>
        public virtual async Task<bool> SetDeleteMarkAsync(bool deleteMark, long deleteUserId, DateTime deleteTime, string whereSql = "", object? parameters = null)
        {
            Expression<Func<Organize, Organize>> columns = x => new Organize() { LastModifyUserId = deleteUserId, LastModifyTime = deleteTime, DeleteMark = deleteMark, DeleteTime = deleteTime, DeleteUserId = deleteUserId };
            return await UpdateAsync(columns, whereSql, parameters);
        }
        #endregion 逻辑删除
        #endregion 修改

        #region 查询
        /// <summary>
        /// 异步根据主键Id列表获取集合数据
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<IEnumerable<Organize>> GetListByIdsAsync(IEnumerable<long> ids)
        {
            return await GetListByWhereAsync(x => ids.Contains(x.Id));
        }
        /// <summary>
        /// 异步根据节点Id获取子节点集合
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IEnumerable<Organize>> GetChildListByIdAsync(long id)
        {
            return (await Db.Queryable<Organize>().ToChildListAsync(x => x.ParentId, id)).Where(x => x.EnabledMark == true && x.DeleteMark == false);
        }
        /// <summary>
        /// 异步根据节点Id获取父节点集合
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IEnumerable<Organize>> GetParentListByIdAsync(long id)
        {
            return (await Db.Queryable<Organize>().ToParentListAsync(x => x.ParentId, id)).Where(x => x.EnabledMark == true && x.DeleteMark == false);
        }
        /// <summary>
        /// 异同步获取父集，递归调用
        /// </summary>
        /// <param name="data"></param>
        /// <param name="id">Id</param>
        /// <returns></returns>
        public async Task<IEnumerable<Organize>> GetParentOrganizesAsync(IEnumerable<Organize> data, long id)
        {
            List<Organize> list = new List<Organize>();
            var organize = data.ToList().FindAll(x => x.Id == id).FirstOrDefault();
            if (organize != null)
            {
                if (organize.ParentId > 0)
                {
                    var ChilList = data.ToList().FindAll(x => x.ParentId == organize.ParentId);
                    foreach (Organize entity in ChilList)
                    {
                        organize.Child = (await GetParentOrganizesAsync(data, entity.Id)).OrderBy(x => x.SortCode).ToList();
                        list.Add(organize);
                    }
                }
            }
            return list;
        }
        /// <summary>
        /// 异步获取子集，递归调用
        /// </summary>
        /// <param name="data"></param>
        /// <param name="parentId">父级Id</param>
        /// <returns></returns>
        public async Task<IEnumerable<Organize>> GetChiltOrganizesAsync(IEnumerable<Organize> data, long parentId)
        {
            List<Organize> list = new List<Organize>();
            var ChilList = data.ToList().FindAll(x => x.ParentId == parentId);
            foreach (Organize entity in ChilList)
            {
                entity.Child = (await GetChiltOrganizesAsync(data, entity.Id)).OrderBy(x => x.SortCode).ToList();
                list.Add(entity);
            }
            return list;
        }
        #endregion 查询

        #endregion 异步方法
    }
}
